<template>
  <panel title="垃圾回收" v-if="current">
    <div class="content">
      <div class="text-center">
        <p class="font-bold">总计</p>
        <p v-text="current.count" />
      </div>
      <div class="text-center">
        <p class="font-bold">总耗时</p>
        <p v-text="`${current.total_time.asSeconds().toFixed(4)}s`" />
      </div>
      <div class="text-center">
        <p class="font-bold">最大耗时</p>
        <p v-text="`${current.max.asSeconds().toFixed(4)}s`" />
      </div>
    </div>
  </panel>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import moment from 'moment';
import panel from './panel.vue';
import api from "@/http/api";

const current = ref(null);

const fetchMetrics = async() => {
  const res = await api.get('/actuator/metrics/jvm.gc.pause');
  const measurements = res.data.measurements.reduce(
    (current, measurement) => ({
      ...current,
      [measurement.statistic.toLowerCase()]: measurement.value,
    }),
    {},
  );
  current.value = {
    ...measurements,
    total_time: moment.duration(toMillis(measurements.total_time, res.baseUnit)),
    max: moment.duration(toMillis(measurements.max, res.baseUnit)),
  };
};

const toMillis = (value, baseUnit) => {
  switch (baseUnit) {
    case 'nanoseconds':
      return value / 1000000;
    case 'microseconds':
      return value / 1000;
    case 'milliseconds':
      return value;
    case 'seconds':
    default:
      return value * 1000;
  }
};

const shutdown = ref(false);
const loopWithDelay = async(taskFn, interval = 1000) => {
  while (!shutdown.value) {
    await taskFn();
    await new Promise(res => setTimeout(res, interval));
  }
}

onMounted(() => {
  loopWithDelay(fetchMetrics);
});

onUnmounted(() => {
  shutdown.value = true;
});
</script>

<style scoped>
.content {
  display: flex;
  flex-direction: row;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: justify;
  -ms-flex-pack: justify;
  justify-content: space-between;
  .text-center {
    text-align: center;
    flex-grow: 1;
  }
  .font-bold {
    margin-bottom: 5px;
  }
}
</style>
